'use client';

import React, { useState, useRef, useEffect, useCallback } from 'react';
import { createPortal } from 'react-dom';

interface PuzzleCaptchaProps {
  onSuccess: () => void;
  onClose?: () => void;
  open: boolean;
}

const PuzzleCaptcha: React.FC<PuzzleCaptchaProps> = ({ onSuccess, onClose, open }) => {
  // 如果在服务端渲染，直接返回null
  if (typeof window === 'undefined') return null;
  const [isDragging, setIsDragging] = useState(false);
  const [sliderPosition, setSliderPosition] = useState(0);
  const [isSuccess, setIsSuccess] = useState(false);
  const [isFailed, setIsFailed] = useState(false);
  const [isMounted, setIsMounted] = useState(false);
  const [feedbackMessage, setFeedbackMessage] = useState('');

  // 随机生成拼图缺口位置 (60-220px) - 缩小随机范围，避免太靠边
  // 用useRef存储目标位置，确保在组件生命周期内不会改变
  const targetPositionRef = useRef(Math.floor(Math.random() * 160) + 60);
  // 转为状态，方便其他地方使用
  const [targetPosition] = useState(targetPositionRef.current);
  
  const containerRef = useRef<HTMLDivElement>(null);
  const sliderRef = useRef<HTMLButtonElement>(null);
  const puzzlePieceRef = useRef<HTMLDivElement>(null);
  const modalRef = useRef<HTMLDivElement>(null);

  // 背景图片和拼图块
  const [bgImage] = useState(Math.floor(Math.random() * 5) + 1); // 1-5随机背景

  // 客户端渲染
  useEffect(() => {
    setIsMounted(true);
  }, []);

  // 处理点击外部关闭
  useEffect(() => {
    const handleClickOutside = (e: MouseEvent) => {
      if (modalRef.current && !modalRef.current.contains(e.target as Node)) {
        onClose?.();
      }
    };

    if (open) {
      document.addEventListener('mousedown', handleClickOutside);
    }

    return () => {
      document.removeEventListener('mousedown', handleClickOutside);
    };
  }, [open, onClose]);

  // 鼠标/触摸事件处理
  const handleMouseDown = (e: React.MouseEvent) => {
    if (isSuccess || isFailed) return;
    setIsDragging(true);
    setFeedbackMessage('');
  };

  const handleTouchStart = (e: React.TouchEvent) => {
    if (isSuccess || isFailed) return;
    setIsDragging(true);
    setFeedbackMessage('');
  };

  const handleMouseMove = (e: MouseEvent) => {
    if (!isDragging || isSuccess || isFailed) return;

    const containerRect = containerRef.current?.getBoundingClientRect();
    if (!containerRect) return;

    // 调整滑块宽度和偏移量计算
    const sliderWidth = 48; // w-12 = 3rem = 48px
    const maxWidth = containerRect.width - sliderWidth;
    
    // 修正鼠标位置计算，减少滑块宽度的一半作为偏移量
    const newPosition = Math.max(0, Math.min(maxWidth, e.clientX - containerRect.left - sliderWidth/2));
    
    // 确保位置更新
    setSliderPosition(newPosition);
    
    // 更新拼图块位置
    if (puzzlePieceRef.current) {
      puzzlePieceRef.current.style.transform = `translateX(${newPosition}px)`;
    }
    
    // 更新滑块位置 - 这是关键修复
    if (sliderRef.current) {
      sliderRef.current.style.transform = `translateX(${newPosition}px)`;
    }

    // 调试日志
    console.log(`当前位置: ${newPosition}, 目标: ${targetPosition}, 差距: ${Math.abs(newPosition - targetPosition)}px`);
  };

  const handleTouchMove = (e: TouchEvent) => {
    if (!isDragging || isSuccess || isFailed) return;
    
    e.preventDefault(); // 防止滚动
    const touch = e.touches[0];
    const containerRect = containerRef.current?.getBoundingClientRect();
    if (!containerRect) return;

    // 与鼠标移动保持一致的计算逻辑
    const sliderWidth = 48;
    const maxWidth = containerRect.width - sliderWidth;
    const newPosition = Math.max(0, Math.min(maxWidth, touch.clientX - containerRect.left - sliderWidth/2));
    
    // 确保位置更新
    setSliderPosition(newPosition);
    
    // 更新拼图块位置
    if (puzzlePieceRef.current) {
      puzzlePieceRef.current.style.transform = `translateX(${newPosition}px)`;
    }
    
    // 更新滑块位置 - 这是关键修复
    if (sliderRef.current) {
      sliderRef.current.style.transform = `translateX(${newPosition}px)`;
    }
    
    // 调试日志
    console.log(`触摸 - 当前位置: ${newPosition}, 目标: ${targetPosition}`);
  };

  const handleMouseUp = () => {
    if (!isDragging || isSuccess || isFailed) return;
    setIsDragging(false);
    
    // 从DOM元素获取当前实际位置，而不是依赖状态变量
    let currentPosition = 0;
    if (sliderRef.current) {
      const transformStyle = window.getComputedStyle(sliderRef.current).transform;
      const matrix = new DOMMatrixReadOnly(transformStyle);
      currentPosition = matrix.m41; // 获取实际的X轴变换值
    }
    
    // 验证是否拼图准确（允许30px误差 - 放宽误差范围）
    const error = Math.abs(currentPosition - targetPosition);
    
    // 调试日志
    console.log('当前位置(DOM):', currentPosition, '状态位置:', sliderPosition, '目标位置:', targetPosition, '误差:', error);
    
    if (error < 30) {
      // 验证成功
      setIsSuccess(true);
      setFeedbackMessage('验证成功');
      
      // 通知父组件
      setTimeout(() => {
        onSuccess();
      }, 1000);
    } else {
      // 验证失败，但不立即显示失败状态，而是给用户一次自动重试的机会
      setSliderPosition(0);
      if (puzzlePieceRef.current) {
        puzzlePieceRef.current.style.transform = `translateX(0px)`;
      }
      if (sliderRef.current) {
        sliderRef.current.style.transform = `translateX(0px)`;
      }
      
      // 为了良好的用户体验，不显示失败状态，而是允许重试
      setFeedbackMessage('请再试一次');
      
      // 如果验证误差太大，显示失败状态
      if (error > 150) {
        setIsFailed(true);
        setFeedbackMessage('验证失败，请重试');
        
        // 1.5秒后自动重置
        setTimeout(() => {
          resetCaptcha();
        }, 1500);
      }
    }
  };

  useEffect(() => {
    if (isDragging) {
      document.addEventListener('mousemove', handleMouseMove);
      document.addEventListener('mouseup', handleMouseUp);
      document.addEventListener('touchmove', handleTouchMove, { passive: false });
      document.addEventListener('touchend', handleMouseUp);
    } else {
      document.removeEventListener('mousemove', handleMouseMove);
      document.removeEventListener('mouseup', handleMouseUp);
      document.removeEventListener('touchmove', handleTouchMove);
      document.removeEventListener('touchend', handleMouseUp);
    }

    return () => {
      document.removeEventListener('mousemove', handleMouseMove);
      document.removeEventListener('mouseup', handleMouseUp);
      document.removeEventListener('touchmove', handleTouchMove);
      document.removeEventListener('touchend', handleMouseUp);
    };
  }, [isDragging]);

  // 重置验证码
  const resetCaptcha = () => {
    setSliderPosition(0);
    setIsSuccess(false);
    setIsFailed(false);
    setFeedbackMessage('');
    
    if (puzzlePieceRef.current) {
      puzzlePieceRef.current.style.transform = `translateX(0px)`;
    }
    
    if (sliderRef.current) {
      sliderRef.current.style.transform = `translateX(0px)`;
    }
  };
  
  if (!isMounted || !open) return null;
  
  return createPortal(
    <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
      <div 
        ref={modalRef}
        className="bg-white rounded-lg shadow-xl overflow-hidden w-[350px] max-w-full"
      >
        {/* 标题 */}
        <div className="flex items-center justify-between px-4 py-3 bg-blue-500 text-white">
          <h3 className="text-lg font-medium">安全验证</h3>
          <button 
            onClick={() => onClose?.()}
            className="text-white hover:text-gray-200"
          >
            ✕
          </button>
        </div>
        
        {/* 验证区域 */}
        <div className="p-4">
          {/* 提示信息 */}
          <div className="text-center mb-4">
            {isFailed ? (
              <p className="text-red-500 font-medium">{feedbackMessage}</p>
            ) : isSuccess ? (
              <p className="text-green-500 font-medium">验证成功</p>
            ) : feedbackMessage ? (
              <p className="text-blue-500 font-medium">{feedbackMessage}</p>
            ) : (
              <p className="text-gray-700">请拖动滑块完成拼图</p>
            )}
          </div>
          
          {/* 拼图区域 */}
          <div 
            ref={containerRef}
            className="relative h-[180px] bg-gray-100 rounded-md overflow-hidden mb-4"
          >
            {/* 背景图片 */}
            <div 
              className="absolute inset-0 bg-cover bg-center"
              style={{ 
                backgroundImage: `url(/auth/captcha/bg-${bgImage}.jpg)`,
                filter: isSuccess ? 'none' : 'brightness(0.9)'
              }}
            />
            
            {/* 辅助对齐线 - 只在拖动时显示 */}
            {isDragging && (
              <div className="absolute top-0 bottom-0 w-px bg-blue-400 opacity-50 pointer-events-none"
                   style={{ left: `${targetPosition + 20}px` }} />
            )}
            
            {/* 拼图缺口 - 方形 */}
            <div 
              className={`absolute w-[40px] h-[40px] rounded-md border-2 transition-colors ${isFailed ? 'border-red-500' : isSuccess ? 'border-green-500' : 'border-blue-300'}`}
              style={{ 
                top: '30px',
                left: `${targetPosition}px`,
                backgroundColor: 'rgba(255, 255, 255, 0.2)',
                boxShadow: isDragging ? '0 0 8px rgba(59, 130, 246, 0.5)' : 'none'
              }}
            />
            
            {/* 拼图块 */}
            <div
              ref={puzzlePieceRef}
              className={`absolute w-[40px] h-[40px] rounded-md cursor-grab ${isDragging ? 'cursor-grabbing' : ''}`}
              style={{ 
                top: '30px',
                left: '0',
                backgroundImage: `url(/auth/captcha/bg-${bgImage}.jpg)`,
                backgroundPosition: `-${targetPosition}px -30px`,
                border: '2px solid',
                borderColor: isDragging ? 'rgba(59, 130, 246, 0.8)' : 'rgba(0, 0, 0, 0.2)',
                boxShadow: isDragging ? '0 0 10px rgba(59, 130, 246, 0.5)' : '0 0 5px rgba(0, 0, 0, 0.3)',
                transition: 'box-shadow 0.2s, border-color 0.2s'
              }}
            />
            
            {/* 失败标记 - 红色圆形 */}
            {isFailed && (
              <div className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2">
                <div className="w-20 h-20 rounded-full bg-red-500 flex items-center justify-center">
                  {/* 可以加入X图标 */}
                </div>
              </div>
            )}
          </div>
          
          {/* 滑块区域 */}
          <div className="relative h-12 bg-gray-100 rounded-full overflow-hidden">
            {/* 滑动进度条 */}
            <div 
              className={`absolute h-full left-0 transition-all ${isSuccess ? 'bg-green-100' : isFailed ? 'bg-red-100' : 'bg-blue-100'}`} 
              style={{ width: `${sliderPosition + 24}px` }}
            />
            
            <button
              type="button"
              disabled={isFailed || isSuccess}
              ref={sliderRef}
              className={`absolute top-0 bottom-0 left-0 w-12 flex items-center justify-center rounded-full cursor-pointer transition-transform
                ${isFailed ? 'bg-red-500 text-white' : 
                  isSuccess ? 'bg-green-500 text-white' : 
                  'bg-blue-500 text-white shadow-lg'}`}
              onMouseDown={handleMouseDown}
              onTouchStart={handleTouchStart}
            >
              {isFailed ? '✕' : isSuccess ? '✓' : '→'}
            </button>
            
            <div className="absolute inset-0 flex items-center justify-center text-sm text-gray-500 pointer-events-none">
              {isFailed ? '请重试' : isSuccess ? '' : '向右滑动完成拼图'}
            </div>
          </div>
          
          {/* 底部操作区 */}
          <div className="flex justify-between mt-4">
            <button
              type="button"
              onClick={resetCaptcha}
              className="text-sm text-gray-500 hover:text-gray-700"
            >
              刷新
            </button>
            
            {isFailed && (
              <button
                type="button"
                onClick={resetCaptcha}
                className="px-4 py-1 bg-red-100 text-red-500 rounded-full text-sm"
              >
                请重试
              </button>
            )}
            
            {isSuccess && (
              <button
                type="button"
                onClick={() => onClose?.()}
                className="px-4 py-1 bg-green-100 text-green-500 rounded-full text-sm"
              >
                确认
              </button>
            )}
          </div>
        </div>
      </div>
    </div>,
    document.body
  );
};



export default PuzzleCaptcha; 